import tkinter as tk
from tkinter import ttk
import rtoml
from tkinter.simpledialog import askstring
import os
#https://github.com/RomneyDa/tkinter-scrollable-frame
class SimpleScrollableFrame(tk.Frame):
    
    def __init__(self, parent, **kwargs):
        self.parent = parent
        
        # Initiate container frame
        tk.Frame.__init__(self, self.parent)

        # Create a frame within a scrollable canvas within the container
        self.canvas = tk.Canvas(self)
        self.frame = tk.Frame(self.canvas)
        
        # (CUSTOM OPTION) Sets scroll sensitivity on a scale of 1 to 10
        if 'scroll_sensitivity' in kwargs and kwargs['scroll_sensitivity'] >= 1 and kwargs['scroll_sensitivity'] <= 10:
            self.scroll_sensitivity = kwargs['scroll_sensitivity']
        else:
            self.scroll_sensitivity = 3 # default scroll sensitivity is 3/10
        
        self.frame.bind("<Configure>",  self._frame_changed)
        self.canvas.bind("<Configure>", self._frame_changed)
        self.canvas.create_window((0, 0), window = self.frame, anchor = "nw")
        
        self.xscrollbar = tk.Scrollbar(self, orient = 'horizontal', command = self.canvas.xview)
        self.canvas.configure(xscrollcommand = self.xscrollbar.set)
        self.yscrollbar = tk.Scrollbar(self, orient = 'vertical', command = self.canvas.yview)
        self.canvas.configure(yscrollcommand = self.yscrollbar.set)
        
        # These functions prevent the canvas from scrolling unless the cursor is in it
        self.canvas.bind('<Enter>', self._enter_frame)
        self.canvas.bind('<Leave>', self._leave_frame)

        # Place the canvas onto the container and weigh relevant rows/cols for proper expansion
        self.canvas.grid(row = 0, column = 0, sticky = tk.S+tk.E+tk.N+tk.W)
        tk.Grid.rowconfigure(self, 0, weight = 1)
        tk.Grid.columnconfigure(self, 0, weight = 1)
        tk.Grid.rowconfigure(self, 1, weight = 0)
        tk.Grid.columnconfigure(self, 1, weight = 0)
    
    def _frame_changed(self, event):
        self.canvas.configure(scrollregion = self.canvas.bbox('all'))
        
        if self.frame.winfo_width() > self.canvas.winfo_width():
            self.showX = True
            self.xscrollbar.grid(row = 1, column = 0, sticky = tk.S+tk.E+tk.N+tk.W)
        else:
            self.showX = False
            self.xscrollbar.grid_forget()
            
        if self.frame.winfo_height() > self.canvas.winfo_height():
            self.showY = True
            self.yscrollbar.grid(row = 0, column = 1, sticky = tk.S+tk.E+tk.N+tk.W)
        else:
            self.showY = False
            self.yscrollbar.grid_forget()

    # Scroll in the Y direction on mouse wheel movement
    def _on_mouse_wheel(self, event):
        self.canvas.yview_scroll(-1*int(event.delta*self.scroll_sensitivity/360), "units")
    
    # Scroll in the X direction on shift + mouse wheel movement
    def _on_shift_mouse_wheel(self, event):
        self.canvas.xview_scroll(-1*int(event.delta*self.scroll_sensitivity/360), "units")

    # These two fucntions simply prevent scrolling unless the cursor is in the frame
    def _enter_frame(self, event):
        if self.showY: self.frame.bind_all("<MouseWheel>", self._on_mouse_wheel)
        if self.showX: self.frame.bind_all("<Shift-MouseWheel>", self._on_shift_mouse_wheel)

    def _leave_frame(self, event):
        if self.showY: self.frame.unbind_all("<MouseWheel>")
        if self.showX: self.frame.unbind_all("<Shift-MouseWheel>")

class AtDaTaBaseFrame:
    def __init__(self, parent):
        self.container = tk.Frame(parent)
        self.currentdatatable=tk.StringVar()
        self.currentdatatable.set("default.toml")
        self.testdata=[[tk.BooleanVar(),tk.StringVar(),tk.StringVar(),tk.IntVar(),tk.IntVar()] for _ in range(100)]
        self._load_cfg()
        


        # Create four scrollable frames and add them to the container
        self.SF1 = SimpleScrollableFrame(self.container)
        self.SF1.grid(row = 0, column = 0, sticky = "wnse")
        

        # Configure all rows and columns present to have the same weight (so they expand with the window)
        tk.Grid.columnconfigure(parent, 0, weight = 1)
        tk.Grid.rowconfigure(parent, 0, weight = 1)
        tk.Grid.columnconfigure(self.container, 0, weight = 1)
        tk.Grid.rowconfigure(self.container, 0, weight = 1)

        
        # Fill each frame with a grid of labels
        self.lots_of_labels()
        self._init()
        self._event()
        # Add the frame
        self.container.grid(row = 0, column = 0, sticky = "wnse")
    def changetestdata(self):
        ss=rtoml.load()
        for idx in ss:
            self.testdata[idx].set()
    def _load_cfg(self,e=1):
        if os.path.exists(os.path.abspath(f"DataTable/{self.currentdatatable.get()}")):
            ss = rtoml.load(open(os.path.abspath(f"DataTable/{self.currentdatatable.get()}"),"r"))
            for items in ss["database"]:
                self.testdata[items[0]][0].set(items[1])
                self.testdata[items[0]][1].set(items[2])
                self.testdata[items[0]][2].set(items[3])
                self.testdata[items[0]][3].set(items[4])
                self.testdata[items[0]][4].set(items[5])
        else:
            if os.path.exists(os.path.abspath("DataTable")):
            # os.mkdir(os.path.abspath(f"DataTable/{self.currentdatatable.get()}"))
                ...
            else:
                os.mkdir(os.path.abspath("DataTable"))
            tempdata = {"database":[[idx,False,"","",0,0] for idx in range(100)]}
            rtoml.dump(tempdata,open(os.path.abspath(f"DataTable/{self.currentdatatable.get()}"),"w"),pretty=True)
    def _save_cfg(self):
        print("save")
        
        ss = {"database":[[idx,item[0].get(),item[1].get(),item[2].get(),item[3].get(),item[4].get()] for idx,item in enumerate(self.testdata)]}
        rtoml.dump(ss,open(os.path.abspath(f"DataTable/{self.currentdatatable.get()}"),"w"),pretty=True)
    def _flush_combobox(self,e):
        self._save_cfg()
        for idx in os.walk("DataTable"):
            self.cb_seletdatatable.configure(values=idx[2])
    # Populates a frame with a grid of labes of given text and same bg as frame
    def lots_of_labels(self):
        self._design()
        # for row in range(dim[0]):
        #     for col in range(dim[1]):
        #         tk.Grid.columnconfigure(parent, col, weight = 1)
        #         tk.Grid.rowconfigure(parent, row, weight = 1)
        #         tk.Label(parent, fg = 'black', text = text, bg = parent.cget('bg')).grid(row = row, column = col)
    def _design(self):
        self._design_hair()
        self._design_head()
        self._design_body()
    def _design_hair(self):
        ss=tk.Frame(self.SF1.frame)
        ss.grid(column=0,row=0,columnspan=5,sticky='w')
        tk.Label(ss,text="选择:").pack(side='left')
        self.cb_seletdatatable=ttk.Combobox(ss,textvariable=self.currentdatatable)
        self.cb_seletdatatable.pack(side="left")
        
        tk.Button(ss,text="新增",command=self._load_cfg).pack(side="left")
        # tk.Entry(ss).pack(side="left")
        tk.Checkbutton(ss,text="循环发送").pack(side="left")
    def _event(self):
        self.cb_seletdatatable.bind("<Button-1>",self._flush_combobox)
        self.cb_seletdatatable.bind("<<ComboboxSelected>>",self._load_cfg)
    def _init(self):
        for idx in os.walk("DataTable"):
            self.cb_seletdatatable.configure(values=idx[2])
    def _design_head(self):
        for idx,txt in enumerate(["num.","HEX","字符串","点击发送","顺序","延时ms"]):
            tk.Label(self.SF1.frame,text=txt).grid(column=idx,row=1)
    def _design_body(self):
        for idx,item in enumerate(self.testdata):
            tk.Label(self.SF1.frame,text=f"{idx}").grid(column=0,row=idx+2)
            tk.Checkbutton(self.SF1.frame,variable=item[0]).grid(column=1,row=idx+2)
            tk.Entry(self.SF1.frame,textvariable=item[1]).grid(column=2,row=idx+2)
            b_atcmd=tk.Button(self.SF1.frame,textvariable=item[2],command=lambda iddx=idx:self._SendAt(iddx))
            b_atcmd.grid(column=3,row=idx+2,sticky='we')
            b_atcmd.bind("<Button-3>",lambda x,y=idx:self._ChangeDescrib(x,y))
            tk.Entry(self.SF1.frame,width=2,textvariable=item[3]).grid(column=4,row=idx+2)
            tk.Entry(self.SF1.frame,width=5,textvariable=item[4]).grid(column=5,row=idx+2)
    def _ChangeDescrib(self,xx,yy):
        ss = askstring("更改描述信息","请输入")
        print(xx)
        self.testdata[yy][2].set(ss)
        # print(yy)
    def _SendAt(self,iidx):
        print(self.testdata[iidx][0].get())
        print(self.testdata[iidx][1].get())
        if self.testdata[iidx][0].get():
            self.CallBack(self.testdata[iidx][1].get(),True,False)
        else:
            self.CallBack(self.testdata[iidx][1].get(),False,False)

    def CallBack(msg,ishex:bool,istri:bool):
        print(msg)
        print(ishex)
# Create and start app

# class testdataloadsave:

if __name__=="__main__":
    root = tk.Tk()
    app = AtDaTaBaseFrame(root)
    root.mainloop()